# Copyright lowRISC contributors (OpenTitan project).
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0

"""Pentest case definition"""

load(
    "//rules/opentitan:defs.bzl",
    "EARLGREY_SILICON_OWNER_ROM_EXT_ENVS",
    "fpga_params",
    "opentitan_test",
    "silicon_params",
)

# Defines default execution environments for penetrationtests targets. All
# opentitan_test must have the following attributes to configure
# each execution environment:
# - cw310
# - cw340
# - silicon
PENTEST_EXEC_ENVS = {
    "//hw/top_earlgrey:fpga_cw340_test_rom": "fpga_cw340",
    "//hw/top_earlgrey:fpga_cw340_sival_rom_ext": "fpga_cw340",
} | EARLGREY_SILICON_OWNER_ROM_EXT_ENVS

FIRMWARE_DEPS_FI = [
    "//sw/device/tests/penetrationtests/firmware/fi:alert_fi",
    "//sw/device/tests/penetrationtests/firmware/fi:crypto_fi",
    "//sw/device/tests/penetrationtests/firmware/fi:ibex_fi",
    "//sw/device/tests/penetrationtests/firmware/fi:lc_ctrl_fi",
    "//sw/device/tests/penetrationtests/firmware/fi:otp_fi",
    "//sw/device/tests/penetrationtests/firmware/fi:rng_fi",
    "//sw/device/tests/penetrationtests/firmware/fi:rom_fi",
    "//sw/device/tests/penetrationtests/firmware/lib:extclk_sca_fi",
    "//sw/device/tests/penetrationtests/firmware/lib:pentest_lib",
    "//sw/device/lib/base:csr",
    "//sw/device/lib/base:status",
    "//sw/device/lib/crypto/drivers:entropy",
    "//sw/device/lib/testing/test_framework:check",
    "//sw/device/lib/testing/test_framework:ottf_main",
    "//sw/device/lib/testing/test_framework:ujson_ottf",
    "//sw/device/lib/ujson",

    # Include all JSON commands.
    "//sw/device/tests/penetrationtests/json:commands",
]

FIRMWARE_DEPS_FI_IBEX = [
    "//sw/device/tests/penetrationtests/firmware/fi:ibex_fi",
    "//sw/device/tests/penetrationtests/firmware/lib:pentest_lib",
    "//sw/device/lib/base:csr",
    "//sw/device/lib/base:status",
    "//sw/device/lib/crypto/drivers:entropy",
    "//sw/device/lib/testing/test_framework:check",
    "//sw/device/lib/testing/test_framework:ottf_main",
    "//sw/device/lib/testing/test_framework:ujson_ottf",
    "//sw/device/lib/ujson",

    # Include all JSON commands.
    "//sw/device/tests/penetrationtests/json:commands",
]

FIRMWARE_DEPS_FI_OTBN = [
    "//sw/device/tests/penetrationtests/firmware/fi:otbn_fi",
    "//sw/device/tests/penetrationtests/firmware/lib:pentest_lib",
    "//sw/device/lib/base:csr",
    "//sw/device/lib/base:status",
    "//sw/device/lib/crypto/drivers:entropy",
    "//sw/device/lib/testing/test_framework:check",
    "//sw/device/lib/testing/test_framework:ottf_main",
    "//sw/device/lib/testing/test_framework:ujson_ottf",
    "//sw/device/lib/ujson",

    # Include all JSON commands.
    "//sw/device/tests/penetrationtests/json:commands",
]

FIRMWARE_DEPS_SCA = [
    "//sw/device/tests/penetrationtests/firmware/sca:aes_sca",
    "//sw/device/tests/penetrationtests/firmware/sca:edn_sca",
    "//sw/device/tests/penetrationtests/firmware/sca:hmac_sca",
    "//sw/device/tests/penetrationtests/firmware/sca:ibex_sca",
    "//sw/device/tests/penetrationtests/firmware/sca:kmac_sca",
    "//sw/device/tests/penetrationtests/firmware/sca:otbn_sca",
    "//sw/device/tests/penetrationtests/firmware/sca:prng_sca",
    "//sw/device/tests/penetrationtests/firmware/sca:sha3_sca",
    "//sw/device/tests/penetrationtests/firmware/sca:trigger_sca",
    "//sw/device/tests/penetrationtests/firmware/lib:extclk_sca_fi",
    "//sw/device/tests/penetrationtests/firmware/lib:pentest_lib",
    "//sw/device/lib/base:csr",
    "//sw/device/lib/base:status",
    "//sw/device/lib/crypto/drivers:entropy",
    "//sw/device/lib/testing/test_framework:check",
    "//sw/device/lib/testing/test_framework:ottf_main",
    "//sw/device/lib/testing/test_framework:ujson_ottf",
    "//sw/device/lib/ujson",

    # Include all JSON commands.
    "//sw/device/tests/penetrationtests/json:commands",
]

FIRMWARE_DEPS_CRYPTOLIB_FI_SYM = [
    "//sw/device/tests/penetrationtests/firmware/sca:trigger_sca",
    "//sw/device/tests/penetrationtests/firmware/fi:cryptolib_fi_sym",
    "//sw/device/tests/penetrationtests/firmware/lib:extclk_sca_fi",
    "//sw/device/tests/penetrationtests/firmware/lib:pentest_lib",
    "//sw/device/lib/base:csr",
    "//sw/device/lib/base:status",
    "//sw/device/lib/crypto/drivers:entropy",
    "//sw/device/lib/testing/test_framework:check",
    "//sw/device/lib/testing/test_framework:ottf_main",
    "//sw/device/lib/testing/test_framework:ujson_ottf",
    "//sw/device/lib/ujson",

    # Include all JSON commands.
    "//sw/device/tests/penetrationtests/json:commands",
]

FIRMWARE_DEPS_CRYPTOLIB_FI_ASYM = [
    "//sw/device/tests/penetrationtests/firmware/sca:trigger_sca",
    "//sw/device/tests/penetrationtests/firmware/fi:cryptolib_fi_asym",
    "//sw/device/tests/penetrationtests/firmware/lib:extclk_sca_fi",
    "//sw/device/tests/penetrationtests/firmware/lib:pentest_lib",
    "//sw/device/lib/base:csr",
    "//sw/device/lib/base:status",
    "//sw/device/lib/crypto/drivers:entropy",
    "//sw/device/lib/testing/test_framework:check",
    "//sw/device/lib/testing/test_framework:ottf_main",
    "//sw/device/lib/testing/test_framework:ujson_ottf",
    "//sw/device/lib/ujson",

    # Include all JSON commands.
    "//sw/device/tests/penetrationtests/json:commands",
]

FIRMWARE_DEPS_CRYPTOLIB_SCA_SYM = [
    "//sw/device/tests/penetrationtests/firmware/sca:cryptolib_sca_sym",
    "//sw/device/tests/penetrationtests/firmware/sca:trigger_sca",
    "//sw/device/tests/penetrationtests/firmware/lib:extclk_sca_fi",
    "//sw/device/tests/penetrationtests/firmware/lib:pentest_lib",
    "//sw/device/lib/base:csr",
    "//sw/device/lib/base:status",
    "//sw/device/lib/crypto/drivers:entropy",
    "//sw/device/lib/testing/test_framework:check",
    "//sw/device/lib/testing/test_framework:ottf_main",
    "//sw/device/lib/testing/test_framework:ujson_ottf",
    "//sw/device/lib/ujson",

    # Include all JSON commands.
    "//sw/device/tests/penetrationtests/json:commands",
]

FIRMWARE_DEPS_CRYPTOLIB_SCA_ASYM = [
    "//sw/device/tests/penetrationtests/firmware/sca:cryptolib_sca_asym",
    "//sw/device/tests/penetrationtests/firmware/sca:trigger_sca",
    "//sw/device/tests/penetrationtests/firmware/lib:extclk_sca_fi",
    "//sw/device/tests/penetrationtests/firmware/lib:pentest_lib",
    "//sw/device/lib/base:csr",
    "//sw/device/lib/base:status",
    "//sw/device/lib/crypto/drivers:entropy",
    "//sw/device/lib/testing/test_framework:check",
    "//sw/device/lib/testing/test_framework:ottf_main",
    "//sw/device/lib/testing/test_framework:ujson_ottf",
    "//sw/device/lib/ujson",

    # Include all JSON commands.
    "//sw/device/tests/penetrationtests/json:commands",
]

def pentest_fi(name, test_vectors, test_args, test_harness):
    """A macro for defining a CryptoTest test case.

    Args:
        name: the name of the test.
        test_vectors: the test vectors to use.
        test_args: additional arguments to pass to the test.
        test_harness: the test harness to use.
    """
    tags = []
    opentitan_test(
        name = name,
        srcs = ["//sw/device/tests/penetrationtests/firmware:firmware_fi.c"],
        fpga = fpga_params(
            timeout = "moderate",
            data = test_vectors,
            tags = tags,
            test_cmd = """
                --bootstrap={firmware}
            """ + test_args,
            test_harness = test_harness,
        ),
        fpga_cw340 = fpga_params(
            timeout = "moderate",
            tags = tags,
            data = test_vectors,
            test_cmd = """
                --bootstrap={firmware}
            """ + test_args,
            test_harness = test_harness,
        ),
        exec_env = PENTEST_EXEC_ENVS,
        silicon = silicon_params(
            timeout = "eternal",
            tags = tags,
            data = test_vectors,
            test_cmd = """
                --bootstrap={firmware}
            """ + test_args,
            test_harness = test_harness,
        ),
        deps = FIRMWARE_DEPS_FI,
    )

def pentest_fi_ibex(name, test_vectors, test_args, test_harness):
    """A macro for defining a CryptoTest test case.

    Args:
        name: the name of the test.
        test_vectors: the test vectors to use.
        test_args: additional arguments to pass to the test.
        test_harness: the test harness to use.
    """
    tags = []
    opentitan_test(
        name = name,
        srcs = ["//sw/device/tests/penetrationtests/firmware:firmware_fi_ibex.c"],
        fpga = fpga_params(
            timeout = "moderate",
            data = test_vectors,
            tags = tags,
            test_cmd = """
                --bootstrap={firmware}
            """ + test_args,
            test_harness = test_harness,
        ),
        fpga_cw340 = fpga_params(
            timeout = "moderate",
            tags = tags,
            data = test_vectors,
            test_cmd = """
                --bootstrap={firmware}
            """ + test_args,
            test_harness = test_harness,
        ),
        exec_env = PENTEST_EXEC_ENVS,
        silicon = silicon_params(
            timeout = "eternal",
            tags = tags,
            data = test_vectors,
            test_cmd = """
                --bootstrap={firmware}
            """ + test_args,
            test_harness = test_harness,
        ),
        deps = FIRMWARE_DEPS_FI_IBEX,
    )

def pentest_fi_otbn(name, test_vectors, test_args, test_harness):
    """A macro for defining a CryptoTest test case.

    Args:
        name: the name of the test.
        test_vectors: the test vectors to use.
        test_args: additional arguments to pass to the test.
        test_harness: the test harness to use.
    """
    tags = []
    opentitan_test(
        name = name,
        srcs = ["//sw/device/tests/penetrationtests/firmware:firmware_fi_otbn.c"],
        fpga = fpga_params(
            timeout = "moderate",
            data = test_vectors,
            tags = tags,
            test_cmd = """
                --bootstrap={firmware}
            """ + test_args,
            test_harness = test_harness,
        ),
        fpga_cw340 = fpga_params(
            timeout = "moderate",
            tags = tags,
            data = test_vectors,
            test_cmd = """
                --bootstrap={firmware}
            """ + test_args,
            test_harness = test_harness,
        ),
        exec_env = PENTEST_EXEC_ENVS,
        silicon = silicon_params(
            timeout = "eternal",
            tags = tags,
            data = test_vectors,
            test_cmd = """
                --bootstrap={firmware}
            """ + test_args,
            test_harness = test_harness,
        ),
        deps = FIRMWARE_DEPS_FI_OTBN,
    )

def pentest_sca(name, test_vectors, test_args, test_harness):
    """A macro for defining a CryptoTest test case.

    Args:
        name: the name of the test.
        test_vectors: the test vectors to use.
        test_args: additional arguments to pass to the test.
        test_harness: the test harness to use.
    """
    tags = []
    opentitan_test(
        name = name,
        srcs = ["//sw/device/tests/penetrationtests/firmware:firmware_sca.c"],
        fpga = fpga_params(
            timeout = "moderate",
            data = test_vectors,
            tags = tags,
            test_cmd = """
                --bootstrap={firmware}
            """ + test_args,
            test_harness = test_harness,
        ),
        fpga_cw340 = fpga_params(
            timeout = "moderate",
            tags = tags,
            data = test_vectors,
            test_cmd = """
                --bootstrap={firmware}
            """ + test_args,
            test_harness = test_harness,
        ),
        exec_env = PENTEST_EXEC_ENVS,
        silicon = silicon_params(
            timeout = "eternal",
            tags = tags,
            data = test_vectors,
            test_cmd = """
                --bootstrap={firmware}
            """ + test_args,
            test_harness = test_harness,
        ),
        deps = FIRMWARE_DEPS_SCA,
    )

def pentest_cryptolib_fi_sym(name, test_vectors, test_args, test_harness, slow_test = False):
    """A macro for defining a CryptoTest test case.

    Args:
        name: the name of the test.
        test_vectors: the test vectors to use.
        test_args: additional arguments to pass to the test.
        test_harness: the test harness to use.
        slow_test: indicate if the test should be run in the nightly CI.
    """
    tags = ["slow_test"] if slow_test else []
    opentitan_test(
        name = name,
        srcs = ["//sw/device/tests/penetrationtests/firmware:firmware_cryptolib_fi_sym.c"],
        fpga = fpga_params(
            timeout = "long",
            data = test_vectors,
            tags = tags,
            test_cmd = """
                --bootstrap={firmware}
            """ + test_args,
            test_harness = test_harness,
        ),
        fpga_cw340 = fpga_params(
            timeout = "long",
            tags = tags,
            data = test_vectors,
            test_cmd = """
                --bootstrap={firmware}
            """ + test_args,
            test_harness = test_harness,
        ),
        exec_env = PENTEST_EXEC_ENVS,
        silicon = silicon_params(
            timeout = "eternal",
            tags = tags,
            data = test_vectors,
            test_cmd = """
                --bootstrap={firmware}
            """ + test_args,
            test_harness = test_harness,
        ),
        deps = FIRMWARE_DEPS_CRYPTOLIB_FI_SYM,
    )

def pentest_cryptolib_fi_asym(name, test_vectors, test_args, test_harness, slow_test = False):
    """A macro for defining a CryptoTest test case.

    Args:
        name: the name of the test.
        test_vectors: the test vectors to use.
        test_args: additional arguments to pass to the test.
        test_harness: the test harness to use.
        slow_test: indicate if the test should be run in the nightly CI.
    """
    tags = ["slow_test"] if slow_test else []
    opentitan_test(
        name = name,
        srcs = ["//sw/device/tests/penetrationtests/firmware:firmware_cryptolib_fi_asym.c"],
        fpga = fpga_params(
            timeout = "long",
            data = test_vectors,
            tags = tags,
            test_cmd = """
                --bootstrap={firmware}
            """ + test_args,
            test_harness = test_harness,
        ),
        fpga_cw340 = fpga_params(
            timeout = "long",
            tags = tags,
            data = test_vectors,
            test_cmd = """
                --bootstrap={firmware}
            """ + test_args,
            test_harness = test_harness,
        ),
        exec_env = PENTEST_EXEC_ENVS,
        silicon = silicon_params(
            timeout = "eternal",
            tags = tags,
            data = test_vectors,
            test_cmd = """
                --bootstrap={firmware}
            """ + test_args,
            test_harness = test_harness,
        ),
        deps = FIRMWARE_DEPS_CRYPTOLIB_FI_ASYM,
    )

def pentest_cryptolib_sca_sym(name, test_vectors, test_args, test_harness, slow_test = False):
    """A macro for defining a CryptoTest test case.

    Args:
        name: the name of the test.
        test_vectors: the test vectors to use.
        test_args: additional arguments to pass to the test.
        test_harness: the test harness to use.
        slow_test: indicate if the test should be run in the nightly CI.
    """
    tags = ["slow_test"] if slow_test else []
    opentitan_test(
        name = name,
        srcs = ["//sw/device/tests/penetrationtests/firmware:firmware_cryptolib_sca_sym.c"],
        fpga = fpga_params(
            timeout = "long",
            data = test_vectors,
            tags = tags,
            test_cmd = """
                --bootstrap={firmware}
            """ + test_args,
            test_harness = test_harness,
        ),
        fpga_cw340 = fpga_params(
            timeout = "long",
            tags = tags,
            data = test_vectors,
            test_cmd = """
                --bootstrap={firmware}
            """ + test_args,
            test_harness = test_harness,
        ),
        exec_env = PENTEST_EXEC_ENVS,
        silicon = silicon_params(
            timeout = "eternal",
            tags = tags,
            data = test_vectors,
            test_cmd = """
                --bootstrap={firmware}
            """ + test_args,
            test_harness = test_harness,
        ),
        deps = FIRMWARE_DEPS_CRYPTOLIB_SCA_SYM,
    )

def pentest_cryptolib_sca_asym(name, test_vectors, test_args, test_harness, slow_test = False):
    """A macro for defining a CryptoTest test case.

    Args:
        name: the name of the test.
        test_vectors: the test vectors to use.
        test_args: additional arguments to pass to the test.
        test_harness: the test harness to use.
        slow_test: indicate if the test should be run in the nightly CI.
    """
    tags = ["slow_test"] if slow_test else []
    opentitan_test(
        name = name,
        srcs = ["//sw/device/tests/penetrationtests/firmware:firmware_cryptolib_sca_asym.c"],
        fpga = fpga_params(
            timeout = "long",
            data = test_vectors,
            tags = tags,
            test_cmd = """
                --bootstrap={firmware}
            """ + test_args,
            test_harness = test_harness,
        ),
        fpga_cw340 = fpga_params(
            timeout = "long",
            tags = tags,
            data = test_vectors,
            test_cmd = """
                --bootstrap={firmware}
            """ + test_args,
            test_harness = test_harness,
        ),
        exec_env = PENTEST_EXEC_ENVS,
        silicon = silicon_params(
            timeout = "eternal",
            tags = tags,
            data = test_vectors,
            test_cmd = """
                --bootstrap={firmware}
            """ + test_args,
            test_harness = test_harness,
        ),
        deps = FIRMWARE_DEPS_CRYPTOLIB_SCA_ASYM,
    )
